Previous Book Contents Book Index Next

Inside Macintosh: 3D Graphics Programming With QuickDraw 3D /
Chapter 1 - Introduction to QuickDraw 3D


About QuickDraw 3D

QuickDraw 3D is a graphics library developed by Apple Computer that you can use to create, configure, and render three-dimensional objects. It is specifically designed to be useful to a wide range of software developers, from those with very little knowledge of 3D modeling concepts and rendering techniques to those with very extensive experience with those concepts and techniques.

At the most basic level, you can use the file format and file-access routines provided by QuickDraw 3D to read and display 3D graphics created by some other application. For example, a word-processing application might want to import a picture created by a 3D modeling or image-capturing application. QuickDraw 3D supports the 3D Viewer, which you can use to display 3D data and objects in a window and allow users limited interaction with that data, without having to learn any of the core QuickDraw 3D application programming interfaces.

Note
See the chapter "3D Viewer" for complete information about the 3D viewer, as well as complete source code samples illustrating how to create and manage a viewer object.
You can also use QuickDraw 3D for more sophisticated applications, such as interactive 3D modeling and rendering, animation, data visualization, or any of thousands of other ways of interpreting and displaying data in three (or more) dimensions. Figure 1-1 illustrates the kinds of images you can produce using QuickDraw 3D. It shows a texture, a wireframe model, and the result of applying the texture to that model. See also Color Plate 3 at the beginning of this book.

Figure 1-1 A simple three-dimensional picture

Modeling and Rendering

To create images such as that shown in Figure 1-1, you typically engage in at least two distinguishable main tasks: modeling and rendering. Modeling is the process of creating a representation of real or abstract objects, and rendering is the process of creating an image (on the screen or some other medium) of a model. QuickDraw 3D subdivides each of these tasks into a number of subtasks.

In QuickDraw 3D, modeling involves

In QuickDraw 3D, rendering involves

Interacting

Often, modeling and rendering are not easily separable, particularly in applications that support interactive 3D modeling. When, for example, the user selects a sphere and drags it using the mouse or other pointing device, the application needs to change the model (reposition the sphere) and render a new image. (Indeed, the application may generate a series of new images to show the sphere changing location as the user drags it.) QuickDraw 3D supports a third main task, interacting with a model (that is, selecting and manipulating objects in the model).

In QuickDraw 3D, interacting involves

QuickDraw 3D supplies an extensive set of routines that you can use to perform these tasks. For complete details, see the chapters "QuickDraw 3D Pointing Device Manager" and "Pick Objects."

Extending QuickDraw 3D

QuickDraw 3D is designed to be easily extensible, so that you can, if necessary, add capabilities that are not part of the basic QuickDraw 3D feature set. For instance, you've already seen that QuickDraw 3D supplies two types of renderers, the wireframe and interactive renderers. The wireframe renderer creates line renderings of models, as illustrated in Figure 1-2.

Figure 1-2 A model rendered by the wireframe renderer

The interactive renderer uses a more complex rendering algorithm that allows illumination and shading effects to be produced. Figure 1-3 shows the same teapot model rendered by the interactive renderer.

Figure 1-3 A model rendered by the interactive renderer

QuickDraw 3D is extensible:

In addition, QuickDraw 3D is designed to be portable to other software platforms and to support a variety of hardware accelerators:

Finally, QuickDraw 3D defines a platform-independent metafile (that is, a file format) for storing and interchanging 3D data. This metafile is intended to provide a standard format according to which applications can read and write 3D data, even applications that use 3D graphics systems other than QuickDraw 3D. QuickDraw 3D itself includes routines that you can use to read and write data in the metafile format. Apple Computer, Inc. also supplies a parser that you can use to read and write metafile data on operating systems that do not support QuickDraw 3D.

Figure 1-4 shows the functional components of QuickDraw 3D.

Figure 1-4 The parts of QuickDraw 3D

Naming Conventions

The QuickDraw 3D application programming interfaces are designed, as much as possible, to mirror the QuickDraw 3D class hierarchy described in the chapter "QuickDraw 3D Objects." They are also designed to exhibit as much uniformity as can reasonably be achieved by names describing a large and heterogeneous collection of objects instantiating classes in that hierarchy. Ideally, once you are acquainted with the various conventions governing the programming interfaces and the class hierarchy, you should be able to make correct guesses about the names of constants, data structures, and routines. In very many cases, the names of constants and routines are largely self-documenting, thanks to a strict adherence to the naming conventions. This section describes those conventions and provides some examples.

Constants

All constants defined in the QuickDraw 3D application programming interfaces have the prefix kQ3. Very simple constants consist solely of the kQ3 prefix and a specific value indicator. Here are some examples:

typedef enum TQ3Boolean {
   kQ3False,
   kQ3True
} TQ3Boolean;
typedef enum TQ3Status {
   kQ3Failure,
   kQ3Success
} TQ3Status;
Most other enumerated constants consist of the standard kQ3 prefix, followed by a type, followed by a specific value. Here are some examples:

typedef enum TQ3Axis {
   kQ3AxisX,
   kQ3AxisY,
   kQ3AxisZ
} TQ3Axis;
Other constants are defined using the C preprocessor #define mechanism. Here are some examples:

#define kQ3ObjectTypeElement  Q3_OBJECT_TYPE('e','l','m','n')
#define kQ3ObjectTypePick     Q3_OBJECT_TYPE('p','i','c','k')
#define kQ3ObjectTypeShared   Q3_OBJECT_TYPE('s','h','r','d')
#define kQ3ObjectTypeView     Q3_OBJECT_TYPE('v','i','e','w')
#define kQ3ObjectTypeInvalid  0
In general, these kinds of constants specify types of objects in the QuickDraw 3D class hierarchy or methods defining the behaviors of those types. These constants use the macros Q3_OBJECT_TYPE or Q3_METHOD_TYPE. See page 3-34 for a definition of these macros.

Data Types

All data structures and data types defined in the QuickDraw 3D application programming interfaces have the prefix TQ3. Like constant names, data type names never contain the underscore character (_). When emphasis is required, subwords of a data type name are capitalized and usually proceed from general to specific.

There are four distinguishable classes in data type names.

   TQ3GeometryObject
   TQ3ViewObject
   TQ3CameraObject
   TQ3StyleObject
   TQ3DrawContextObject
   TQ3TriangleData
   TQ3BoxData
   TQ3OrthographicCameraData
   TQ3Point3D
   TQ3Vector2D
   TQ3ColorRGB
   TQ3ColorARGB
IMPORTANT
All floating-point numbers used in the QuickDraw 3D application programming interfaces are single precision.

Functions

All functions defined in the QuickDraw 3D application programming interfaces have the prefix Q3. The class of an identifier immediately follows its type prefix. Then the method occurs, separated from the class by an underscore. A method is almost always expressed as a verb-noun sequence. Here are some examples:

Q3Polygon_GetVertexPosition
Q3NURBCurve_SetControlPoint
Q3Light_SetBrightness
Q3SpotLight_GetFallOff
Q3View_GetLocalToWorldInverseTransposeMatrixState
Q3Triangle_New
Some functions are so simple that they have no distinguishable class and method. Here are some examples:

Q3Initialize
Q3IsInitialized
Q3Exit
As much as possible, function parameters are ordered consistently throughout the application programming interfaces. In virtually all cases, the first parameter is a data type that corresponds to the object being operated on. When there are two or more additional parameters, they are placed in their natural or intuitive ordering.

Most QuickDraw 3D functions return a status code, which is of type TQ3Status. A status code is either kQ3Success or kQ3Failure, indicating that the function has succeeded or failed. When a function fails, you can call a further function to get a specific error code. Alternatively, you can install an error-reporting callback routine to handle failures. See the chapter "Error Manager" for complete details on handling errors.

Functions that create opaque objects usually return a function result whose type is a reference to the type of the newly created object (for instance, TQ3CameraObject for a new camera object). An object reference is an opaque pointer to the object. When these kinds of routines fail, they return the value NULL.

Retained and Immediate Modes

A graphics system operates in retained mode if it retains a copy of all the data describing a model. In other words, a retained mode graphics system requires you to completely specify a model by passing model data to the system using predefined data structures. The graphics system organizes the data internally, usually in a hierarchical database. Once an object is added to that database, you can change the object only by calling specific editing routines provided by the graphics system.

By contrast, a graphics system operates in immediate mode if the application itself maintains the data that describe a model. For example, original QuickDraw is a two-dimensional graphics system that operates in immediate mode. You draw objects on the screen, using QuickDraw, by calling routines that completely specify the objects to be drawn. QuickDraw does not maintain any information about a picture internally; it simply takes the data provided by the application and immediately draws the appropriate objects.

Note
OpenGLÅ is an example of a 3D graphics system that operates in immediate mode. QuickDraw GX is an example of a 2D graphics system that operates in retained mode.
QuickDraw 3D supports both immediate and retained modes of specifying and drawing models. The principal advantage of immediate mode imaging is that the model data is immediately available to you and is not duplicated by the graphics system. The data is stored in whatever form you like, and you can change that data at any time. The main disadvantage of immediate mode imaging is that you need to maintain the sometimes quite lengthy object data, and you need to perform geometric operations on that data yourself. In addition, it can be difficult to accelerate immediate mode rendering, because you generally need to specify the entire model to draw a single frame, whether or not the entire model has changed since the previous frame. This can involve passing large amounts of data to the graphics system.

Retained mode imaging typically supports higher levels of abstraction than immediate mode imaging and is more amenable to hardware acceleration and caching. In addition, the hierarchical arrangement of the model data allows the graphics system to perform very quick updates whenever the data is altered. To avoid duplicating data between your application and the graphics system's database, your application should match the data types of the graphics system and use the extensive editing functions to change a model's data.

Another important advantage of retained mode imaging is that it's very easy to read and write retained objects.

To create a point, for example, in retained mode, you fill in a data structure of type TQ3PointData and pass it to the Q3Point_New function. This function copies the data in that structure and returns an object of type TQ3GeometryObject, which you use for all subsequent operations on the point. For example, to draw the point in retained mode, you pass that geometric object returned by Q3Point_New to the Q3Geometry_Submit function inside a rendering loop. To change the data associated with the point, you call point-editing functions, such as Q3Point_GetPosition and Q3Point_SetPosition. Finally, when you have finished using the point, you must call Q3Object_Dispose to have QuickDraw 3D delete the point from its internal database.

It's much simpler to draw a point in immediate mode. You do not need to call any QuickDraw 3D routine to create a point in immediate mode; instead, you merely have to maintain the point data yourself, typically in a structure of type TQ3PointData. To draw a point in immediate mode, you call the Q3Point_Submit function, passing it a pointer to that structure. Note, however, that when using immediate mode, you need to know exactly what types of objects you're drawing and hardcode the appropriate routines in your source code.

Note
Immediate mode rendering does not require any memory permanently allocated to QuickDraw 3D, but it might require QuickDraw 3D to perform temporary allocations while rendering is occurring.
In general, if most of a model remains unchanged from frame to frame, you should use retained mode imaging to create and draw the model. If, however, many parts of the model do change from frame to frame, you should probably use immediate mode imaging, creating and rendering a model on a shape-by-shape basis. You can, of course, use a combination of retained and immediate mode imaging: you can create retained objects for the parts of a model that remain static and draw quickly changing objects in immediate mode.


Previous Book Contents Book Index Next

© Apple Computer, Inc.
11 JUL 1996